<template>
  <div id="aliasManager" class="list-index">
    <div class="run-box">
      <div class="state-box">
        <div class="run-label">实例规格组</div>
      </div>
    </div>
    <div class="top-button" v-if="userType >= 5">
      <button class="btn new" @click="dialogVisibtn()">新建实例规格组</button>
    </div>
    <div class="table-box">
      <div class="refresh">
        <el-input v-model="getbucket.name" placeholder="请输入组名称进行筛选" clearable :prefix-icon="Search" @input="getInstanceList"> </el-input>
      </div>
      <el-table
        :data="tableData"
        style="width: 100%"
        :header-cell-style="{ background: '#fafafe', color: '#1d1d1f' }"
        :border="true"
        :default-sort="{ prop: 'creation_time', order: 'descending' }"
      >
        <el-table-column label="组名称" class-name="elcell" show-overflow-tooltip>
          <template #default="scope">
            <div class="toDetails" @click="toDetails(scope.row.id)">
              {{ scope.row.name }}
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="resource_specification" label="实例规格">
          <template #default="scope">
            <el-tooltip class="box-item" effect="dark" placement="bottom-start" style="width: 200px">
              <div>{{ scope.row.resource_specification }}</div>
              <template #content>
                <div slot="content" v-for="(val, key) in scope.row.flavor">{{ val }}</div>
              </template>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column prop="instance_type" label="实例类型" />
        <el-table-column prop="fleet_count" label="关联Fleet数量" />
        <el-table-column prop="creation_time" label="创建时间" :formatter="timeFormatUTC" />
        <el-table-column fixed="right" label="操作" width="200">
          <template #default="scope">
            <div class="actions-box">
              <div class="actions-details" @click="updataInstance(scope.$index, scope.row)" v-if="userType >= 5">修改</div>
              <div class="line" v-if="userType >= 5"></div>
              <div class="actions-delete" @click="deleteAs(scope.row.name, scope.row.id)" v-if="userType >= 5">删除</div>
              <div class="line" v-if="userType >= 5"></div>
              <div class="actions-delete" @click="toDetails(scope.row.id)">详情</div>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 新建实例规格组弹框 -->
    <el-dialog :title="titleType + '实例规格组'" v-model="dialogVisible" width="30%" center>
      <div class="chooseCreationMethod" v-if="show">
        <span>创建方式</span>
        <el-radio-group class="radios" v-model="creationMethod">
          <el-radio-button label="1">通过VM创建</el-radio-button>
          <el-radio-button label="2">通过POD创建</el-radio-button>
        </el-radio-group>
      </div>
      <div class="inputAll" v-if="creationMethod == '1'">
        <div class="inputSize">
          <el-form :model="formModel" ref="assRef" :rules="rules" label-position="left">
            <el-form-item prop="name" :rules="rules.name">
              <template #label>
                <div class="item-label">组名称</div>
              </template>
              <el-input placeholder="请输入实例规格组名" class="elInput" v-model="formModel.name" maxlength="1024" minLength="1" />
            </el-form-item>
          </el-form>
          <el-scrollbar>
            <div class="selected">已选实例规格：{{ selectedCount }}</div>
            <el-tree :data="selectedOptions" :props="defaultProps" :default-expand-all="true" />
          </el-scrollbar>
        </div>
        <div class="inputSize">
          <el-input v-model="filterText" @keyup.enter.native="filterInput" placeholder="请输入关键字进行搜索" :suffix-icon="Search" />
          <el-scrollbar>
            <el-tree
              ref="treeRef"
              :data="exampleOptions"
              show-checkbox
              :props="defaultProps"
              node-key="label"
              :filter-node-method="filterNode"
              :default-checked-keys="tableData1"
              @check="handleCheckChange"
            />
          </el-scrollbar>
        </div>
      </div>
      <div v-else="creationMethod == '2'" class="formData">
        <el-form :model="formModel" ref="assRef" :rules="rules" label-position="right">
          <el-form-item prop="name" :rules="rules.name">
            <template #label>
              <div class="item-label">组名称</div>
            </template>
            <el-input placeholder="请输入实例规格组名" class="elInput" v-model="formModel.name" />
          </el-form-item>
          <el-form-item prop="cpu" :rules="rules.cpu">
            <template #label>
              <div class="item-label">CPU</div>
            </template>
            <el-input-number v-model="formModel.cpu" :min="1" :max="64" @change="handleChange" />
          </el-form-item>
          <el-form-item prop="memory" :rules="rules.memory">
            <template #label>
              <div class="item-label">memory</div>
            </template>
            <el-input-number v-model="formModel.memory" :min="minData" :max="maxData" />
          </el-form-item>
        </el-form>
        <div class="dialog_hint">
          <el-icon>
            <InfoFilled />
          </el-icon>
          <p>cpu的区间为[1,64],memory的区间为[2,512],memory和cpu比值的区间为[2,8]</p>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="SureInstance(assRef)">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <div class="demo-pagination-block">
      <el-pagination
        v-model:current-page="getbucket.offset"
        v-model:page-size="getbucket.limit"
        :page-sizes="[10, 20, 50, 100]"
        :small="small"
        :disabled="disabled"
        :background="background"
        layout="total, sizes, prev, pager, next, jumper"
        :total="tableTotal"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import appStore from '@/store'
  import { reactive, ref, watch, nextTick } from 'vue'
  import { timeFormatUTC } from '@/utils/formatter'
  import { Search } from '@element-plus/icons-vue'
  import UserService, { instances, deleteList } from '@/api/userService'
  import { ElMessage, ElMessageBox, FormRules, FormInstance } from 'element-plus'
  import router from '@/router'
  const dialogVisible = ref(false)
  const filterText = ref('')
  const titleType = ref('')
  const oldName = ref('')
  const idData = ref('')
  const small = ref(false)
  const disabled = ref(false)
  const background = ref(true)
  const show = ref(false)
  let tableTotal = ref(0)
  const assRef = ref<FormInstance>()
  const creationMethod = ref('1')
  const minData = ref(2)
  const maxData = ref(512)
  let exampleOptions = reactive([] as any[])
  let selectedOptions = reactive([] as any[])
  let tableData = ref()
  const treeRef = ref(null) as any

  let userType = ref()
  userType.value = localStorage.getItem('UserType') as string
  const handleSizeChange = (val: number) => {
    getbucket.limit = val
    getbucket.offset = 1
    getInstanceList()
  }
  const handleCurrentChange = (val: number) => {
    getbucket.offset = val
    getInstanceList()
  }
  watch(filterText, (val: any) => {
    treeRef.value!.filter(val)
  })
  const filterInput = () => {
    treeRef.value.filter(filterText)
  }
  const filterNode = (value: string, data: any, node: any) => {
    if (!value) {
      node.expanded = false
      return true
    }
    let val = value.toLowerCase()
    return chooseNode(val, data, node)
  }

  // 过滤
  const chooseNode = (value: any, data: any, node: any) => {
    if (data.label.indexOf(value) !== -1) {
      return true
    }
    const level = node.level
    if (level === 1) {
      return false
    }
    let parentData = node.parent
    let index = 0
    while (index < level - 1) {
      if (parentData.data.label.indexOf(value) !== -1) {
        return true
      }
      parentData = parentData.parent
      index++
    }
    return false
  }
  const defaultProps = {
    children: 'children',
    label: 'label'
  }
  const getInstanceList = async () => {
    let res = await UserService.getInstanceList(getbucket)
    if (res.status == 200 && res?.data.resource_specifications) {
      tableData.value = res?.data.resource_specifications
      tableTotal.value = res.data.count
    } else {
      tableData.value = []
    }
  }
  const dialogVisibtn = async () => {
    creationMethod.value = '1'
    dialogVisible.value = true
    titleType.value = '新建'
    show.value = true
    formModel.name = ''
    selectedOptions.length = 0
    selectedCount.value = 0
    nextTick(() => {
      treeRef.value.setCheckedKeys([])
    })
  }
  const formModel = reactive<{
    name: string
    cpu: number
    memory: number
  }>({
    name: '',
    cpu: 1,
    memory: 2
  })

  const rules = reactive<FormRules>({
    name: [{ required: true, message: '请输入实例组名称', trigger: 'blur' }]
  })
  const handleChange = (val: any) => {
    if (val) {
      minData.value = 2 * val
      maxData.value = 8 * val
    }
  }

  const handleCheckChange = async (data: any, a: any) => {
    let newArr = reactive([] as any[])
    let isShow = a.checkedKeys.includes(data.value)
    let isLevel1 = !!data.children
    if (isLevel1) {
      if (isShow) {
        let children = reactive([] as any[])
        data.children.forEach((cItem: any) => {
          children.push(cItem)
        })
        newArr.push({
          label: data.label,
          value: data.value,
          children: children
        })
        let checkedKeys = [data.label, ...children.map((cItem) => cItem.label)]
        treeRef.value.setCheckedKeys(checkedKeys)
        selectedOptions.length = 0
        selectedOptions.push(...newArr)
      } else {
        treeRef.value.setCheckedKeys([])
        selectedOptions.length = 0
      }
    } else {
      let label = data.label
      let level1Arr = exampleOptions.filter((item) => {
        let childrenLabels = item.children.map((cItem: any) => cItem.label)
        return childrenLabels.includes(label)
      })
      let level1Item = level1Arr[0] || {}
      let curSelectedOption = selectedOptions[0] || {}
      let children = []
      if (curSelectedOption.label === level1Item.label) {
        if (isShow) {
          children = [...curSelectedOption.children, { label: data.label, value: data.value }]
        } else {
          children = curSelectedOption.children.filter((cItem: any) => cItem.label !== label)
        }
        if (children.length) {
          newArr.push({
            label: level1Item.label,
            value: level1Item.value,
            children: children
          })
        }
      } else {
        newArr.push({
          label: level1Item.label,
          value: level1Item.value,
          children: [{ label: data.label, value: data.value }]
        })
      }
      let checkedKeys = []
      if (newArr[0]) {
        if (newArr[0].children.length === level1Item.children.length) {
          checkedKeys = [level1Item.label, ...newArr[0].children.map((cItem: any) => cItem.label)]
        } else {
          checkedKeys = [newArr[0].children.map((cItem: any) => cItem.label)]
        }
        if (curSelectedOption.label === level1Item.label) {
          treeRef.value.setChecked(checkedKeys, true, true)
        } else {
          treeRef.value.setCheckedKeys(checkedKeys, false)
        }
      } else {
        treeRef.value.setCheckedKeys([])
      }
      if (newArr.length) {
        selectedOptions.length = 0
        selectedOptions.push(...newArr)
      } else {
        selectedOptions.length = 0
      }
    }
  }
  let getbucket: instances = reactive({
    name: '',
    resource_specification_id: '',
    project_id: appStore.userStore.project_id,
    region: appStore.userStore.region,
    offset: 1,
    limit: 10,
    fleets: { name: '' },
    resource_specification: ''
  })
  const instanceLists: deleteList = reactive({
    project_id: appStore.userStore.project_id,
    resource_specification_id: ''
  })
  let selectedCount = ref(0)
  watch(selectedOptions, (val: any) => {
    val.forEach((itCem: any) => {
      selectedCount.value = itCem.children.length
      if (itCem.children && itCem.children.length > 10) {
        ElMessageBox.alert('实例规格列表最多可选择十条', '提示', {
          confirmButtonText: 'OK',
          callback: () => {}
        })
      }
    })
  })

  const getResourceSpecification = async () => {
    let res = await UserService.getResourceSpecification(getbucket)
    if (res.status == 200) {
      let object = res.data
      for (const key in object) {
        if (Object.prototype.hasOwnProperty.call(object, key)) {
          const element = object[key]
          let obj1 = { value: key, label: key, children: [] as any[] }
          exampleOptions.push(obj1)
          if (Array.isArray(element)) {
            element.forEach((item: any) => {
              obj1.children.push({
                value: item,
                label: item
              })
            })
          }
        }
      }
    }
  }
  let tableData1 = reactive([] as any[])
  const updataInstance = (index: any, row: any) => {
    dialogVisible.value = true
    if (row.instance_type == 'VM') {
      creationMethod.value = '1'
      nextTick(() => {
        treeRef.value.setCheckedKeys(tableData1)
      })
      let defaultOptions = reactive([] as any[])
      let object = row.resource_specification
      const element = row.flavor
      let obj = { value: object, label: object, children: [] as any[] }
      defaultOptions.push(obj)
      if (Array.isArray(element)) {
        element.forEach((item: any) => {
          obj.children.push({
            value: item,
            label: item
          })
        })
      }
      selectedOptions.length = 0
      selectedOptions.push(obj)
      tableData1 = []
      selectedOptions.forEach((itCem: any) => {
        itCem.children.forEach((it: any) => {
          tableData1.push(it.label)
        })
      })
    } else {
      creationMethod.value = '2'
      formModel.cpu = Number(row.flavor[0].replace(/[^\d]/g, ''))
      formModel.memory = Number(row.flavor[1].replace(/[^\d]/g, ''))
    }
    show.value = false
    titleType.value = '修改'
    formModel.name = row.name
    oldName.value = row.name
    idData.value = row.id
  }
  const deleteAs = (name: string, id: string) => {
    ElMessageBox.confirm(`确认删除此条数据？\n名称: ${name}\nid: ${id}  `, '警告', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        instanceLists.resource_specification_id = id
        let res = await UserService.deleteInstanceList(instanceLists)
        if (res.status === 204) {
          ElMessage({
            message: '删除成功！',
            type: 'success'
          })
          getInstanceList()
        } else {
          ElMessage({
            type: 'info',
            message: '删除失败'
          })
        }
      })
      .catch(() => {})
  }

  let flavorData = reactive([] as any[])
  let absolutea
  const SureInstance = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate(async (valid, fields) => {
      if (valid) {
        let determineData
        flavorData = []
        selectedOptions.forEach((item: any) => {
          determineData = item.label
          item.children.forEach((it: any) => {
            flavorData.push(it.label)
          })
        })
        if (flavorData.length > 10) {
          ElMessageBox.alert('实例规格列表最多可选择十条', '提示', {
            confirmButtonText: 'OK',
            callback: () => {}
          })
        } else {
          if (creationMethod.value == '2') {
            absolutea = {
              name: titleType.value == '新建' ? formModel.name : oldName.value,
              resource_specification: 'pod',
              region: appStore.userStore.region,
              instance_type: 'POD',
              flavor: [`{"cpu":${formModel.cpu},"memory":${formModel.memory}}`],
              project_id: appStore.userStore.project_id,
              new_name: titleType.value == '新建' ? '' : formModel.name,
              id: titleType.value == '新建' ? '' : idData.value
            }
          } else {
            absolutea = {
              name: titleType.value == '新建' ? formModel.name : oldName.value,
              resource_specification: determineData,
              id: titleType.value == '新建' ? '' : idData.value,
              project_id: appStore.userStore.project_id,
              region: appStore.userStore.region,
              flavor: flavorData,
              new_name: titleType.value == '新建' ? '' : formModel.name,
              instance_type: 'VM'
            }
          }
          if (titleType.value == '新建') {
            try {
              let res = await UserService.createInstanceList(absolutea)
              if (res.status < 300) {
                ElMessage({
                  message: '创建成功',
                  type: 'success'
                })
                tableData.value.push(absolutea)
                dialogVisible.value = false
                getInstanceList()
              }
            } catch (err) {
              ElMessage.error('创建失败')
            }
          } else {
            try {
              let res = await UserService.updataInstanceList(absolutea)
              if (res.status < 300) {
                ElMessage({
                  message: '修改成功',
                  type: 'success'
                })
                dialogVisible.value = false
                getInstanceList()
              }
            } catch (err) {
              ElMessage.error('修改失败')
            }
          }
        }
      }
    })
  }
  const toDetails = async (id: string) => {
    router.push({
      name: 'instanceDetails',
      params: {
        id
      }
    })
  }
  getResourceSpecification()
  getInstanceList()
</script>
<style lang="scss" scoped>
  @import '@/assets/scss/list.scss';
  .search-box {
    margin-bottom: 20px;
  }
  .refresh {
    margin-bottom: 20px;
  }
  .inputAll {
    display: flex;
    margin-bottom: -10px;
    .inputSize {
      width: 260px;
      margin-right: 20px;
      .selected {
        font-size: 14px;
        font-weight: Bold;
        color: #252b3a;
        margin-left: 10px;
        margin-top: 10px;
      }
    }
  }
  .el-tree {
    max-height: 450px;
    font-size: 14px;
  }
  .el-scrollbar {
    height: 450px;
    margin-top: 10px;
  }
  .dialog-footer .el-button {
    width: 120px;
    margin-right: 20px;
    margin-bottom: 20px;
  }
  .chooseCreationMethod {
    display: flex;
    align-items: center;
    margin-bottom: 30px;
    span {
      font-size: 14px;
      color: #0d0d0e;
      margin: 0 28px 0 8px;
    }
    .radios {
      :deep(.el-radio-button__inner) {
        width: 150px;
        height: 30px;
        border-radius: 2px;
        font-size: 14px;
        text-align: CENTER;
        color: #8a8e99;
      }
      :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
        background-color: #ecf2ff;
        border: 1px solid #325cb0;
        color: #325cb0;
        box-shadow: none;
      }
    }
  }
  .formData {
    .elInput {
      width: 350px;
    }
    :deep(.el-form-item__label) {
      width: 73px;
      margin-right: 20px;
    }
    .el-icon {
      margin: 6px 0px 0px 6px;
      color: #b4b6be;
    }
    .dialog_hint {
      margin-top: 24px;
      display: flex;
      min-height: 35px;
      background: #ecf2ff;
      border: 1px solid #d1d1d3;
      border-radius: 2px;
      p {
        color: #8a8e99;
        font-size: 14px;
        line-height: 35px;
      }
      .el-icon {
        width: 1em;
        height: 1em;
        margin: 12px 6px 0 6px;
        color: #8a8e99;
        border: none;
      }
    }
  }
</style>
